package com.nave.view;

import java.util.ArrayList;

import nave.Constants;
import nave.control.Simulation;
import nave.model.GameObject;
import nave.model.Player;
import nave.model.Shot;
import nave.model.Spaceship;
import nave.model.Stage;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.drawable.Drawable;
import android.util.AttributeSet;
import android.util.Log;
import android.view.SurfaceView;

import com.nave.R;

/*
 * For OpenGL
 * extends GLSurfaceView or have an instance of it
 */
public class GameView extends SurfaceView
{
	/*
	 * Attributes
	 */
	private static ArrayList<GameObject> objects;
	private static GameView singleton;


	/*
	 * Constructor
	 */
	public GameView(Context cont, AttributeSet attrs)
	{	
		super(cont, attrs);
		
		// Gets the images
		player = new Drawable[]
				{
				cont.getResources().getDrawable(R.drawable.player_r),
				cont.getResources().getDrawable(R.drawable.player_u),
				cont.getResources().getDrawable(R.drawable.player_l),
				cont.getResources().getDrawable(R.drawable.player_d)
				};
		enemy = new Drawable[]
				{
				cont.getResources().getDrawable(R.drawable.enemy_r),
				cont.getResources().getDrawable(R.drawable.enemy_u),
				cont.getResources().getDrawable(R.drawable.enemy_l),
				cont.getResources().getDrawable(R.drawable.enemy_d)
				};
		explosion = new Drawable[]
				{
				cont.getResources().getDrawable(R.drawable.explosion1)
				};
//		item = new Drawable[] { cont.getResources().getDrawable(R.drawable.) }; // TODO images
		shot = new Drawable[]
				{
				cont.getResources().getDrawable(R.drawable.shot),
				cont.getResources().getDrawable(R.drawable.shot)
				};
		block = cont.getResources().getDrawable(R.drawable.block);
		background = new Drawable[]
				{
				cont.getResources().getDrawable(R.drawable.bg_sky1),
				cont.getResources().getDrawable(R.drawable.bg_sky2)
				};

		setFocusable(true);
		
        singleton = this;
	}


	/*
	 * Public methods
	 */
	public static void setObjects(ArrayList<GameObject> list)
	{
		objects = list;
	}
	
	public static GameView getReference()
	{
		return singleton;
	}

	public void dispose()
	{
		objects.clear();
	}

	/*
	 *	Drawing 
	 */
	private static Drawable player[];
//	private int playerAnimationCounter = 0;

	private static Drawable enemy[];
//	private int enemyAnimationCounter = 0;

	private static Drawable explosion[];
//	private static Drawable item[];
	private static Drawable shot[];
	private static Drawable block;

	private static Drawable background[];
	
  	public void update()
  	{
  		if ( getHolder().getSurface().isValid() )
  		{
  			Canvas canvas = getHolder().lockCanvas();
  			
  			canvas.drawColor(Color.BLACK);

  			drawStage(canvas);
  			drawObjects(canvas);
  			
  			drawStatusBar(canvas);

  			getHolder().unlockCanvasAndPost(canvas);
  		}
  	}

	static int bgY[] = new int[] { 0, 0, Constants.SCREEN_HEIGHT, Constants.SCREEN_HEIGHT };
	private void drawStage(Canvas canvas)
	{
		for ( int i = 0; i < bgY.length; i++ )
		{
			background[i%2].setBounds(0, bgY[i], Constants.SCREEN_WIDTH,
					bgY[i] + Constants.SCREEN_HEIGHT );
			background[i%2].draw(canvas);
		} 

		try
		{
			for (int i = 0; i < Stage.getRows(); i++)
			{
				for (int j = 0; j < Stage.getCols(); j++)
				{
					if ( Stage.getPositionOnStage(i, j) == Constants.WALL )
					{
						block.setBounds( j * Constants.TILE_WIDTH,
								i * Constants.TILE_HEIGHT,
								(j+1) * Constants.TILE_WIDTH,
								(i+1) * Constants.TILE_HEIGHT );
						block.draw(canvas);
					}
				}
			}
		}
		catch (NullPointerException e)
		{
			Log.w("NAVE", "Stage matriz not initialized");
		}

		for (int i = 0; i < bgY.length; i++)
		{
			bgY[i] += 1 + i%2;
			if ( bgY[i] >= Constants.SCREEN_HEIGHT )
				bgY[i] = -Constants.SCREEN_HEIGHT + 1 ;
		}
	}

	private void drawObjects(Canvas canvas)
	{
		if ( objects != null )
		{
			for (int i = 0; i < objects.size(); i++)
			{
				try
				{
					getDrawImage(objects.get(i)).draw(canvas);
				}
				catch (NullPointerException e)
				{
					Log.w("NAVE", "Null pointer for the drawing");
				}
			}
		}
	}
	private Drawable getDrawImage(GameObject g)
	{
  		int width = 0,
  			height = 0;
  		
  		Drawable image = null;
  		
  		switch (g.getId())
  		{
		case Constants.ID_PLAYER:
			switch ( ((Spaceship) g).getDirection() )
			{
			case Spaceship.DIRECTION_RIGHT:
				image = player[0];
				break;
			case Spaceship.DIRECTION_UP:
				image = player[1];
				break;
			case Spaceship.DIRECTION_LEFT:
				image = player[2];
				break;
			case Spaceship.DIRECTION_DOWN:
				image = player[3];
				break;
			default:
				image = player[0];
			}
  			width = Constants.TILE_WIDTH;
  			height = Constants.TILE_HEIGHT;
			break;
		case Constants.ID_BULLETS:
			image = shot[0];
  			width = Shot.WIDTH;
  			height = Shot.HEIGHT;
			break;
		case Constants.ID_EXPLOSION:
			image = explosion[0];
  			width = Constants.TILE_WIDTH;
  			height = Constants.TILE_HEIGHT;
			break;
		case Constants.ITEM:
//			image = item; // TODO
			width = Constants.TILE_WIDTH;
  			height = Constants.TILE_HEIGHT;
			break;
		default:
			if ( g.getId() >= Constants.ID_ENEMY_BASE )
			{
				switch ( ((Spaceship) g).getDirection() )
				{
				case Spaceship.DIRECTION_RIGHT:
					image = enemy[0];
					break;
				case Spaceship.DIRECTION_UP:
					image = enemy[1];
					break;
				case Spaceship.DIRECTION_LEFT:
					image = enemy[2];
					break;
				case Spaceship.DIRECTION_DOWN:
					image = enemy[3];
					break;
				default:
					image = enemy[0];
				}
				width = Constants.TILE_WIDTH;
				height = Constants.TILE_HEIGHT;
			}
		}
  		if ( image != null )
  		{
  			image.setBounds(g.getDrawPositon().x,
					g.getDrawPositon().y,
					g.getDrawPositon().x + width,
					g.getDrawPositon().y + height);
  		}
		return image;
	}

	private void drawStatusBar(Canvas canvas)
  	{
  		{
  	    	//This saves off the matrix that the canvas applies to draws, so it can be restored later. 
  	        canvas.save(); 
 
  	        canvas.rotate(-90);

  	        //draw the text with the matrix applied.
  	        Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
  	        p.setColor(Color.WHITE);
  	        p.setTextSize(25);
  	        p.setTextAlign(Align.LEFT);
  	        
  	        int padding = -5 + Constants.STATUS_BAR_WIDTH;
  	        
  	        String points = "Points: " + Simulation.getSimulation().score();
  	        
  	        // TODO change this
  	        Player pl = null;
  	        for ( GameObject o : objects )
  	        {
  	        	if (o instanceof Player)
  	        	{
  	        		pl = (Player) o;
  	        		break;
  	        	}
  	        }
  	        
  	        String lives = "Lives: ";
  	        if ( pl != null )
  	        	lives += pl.getLives(); 

//  	        canvas.drawText(points, 0, -Constants.SCREEN_WIDTH - padding, p);
//  	        canvas.drawText(lives, Constants.SCREEN_HEIGHT / 2, -Constants.SCREEN_WIDTH - padding, p);
  	        canvas.drawText(points, -Constants.SCREEN_HEIGHT, Constants.SCREEN_WIDTH + padding, p);
  	        canvas.drawText(lives, - 3 * Constants.SCREEN_HEIGHT / 8, Constants.SCREEN_WIDTH + padding, p);


  	        //restore the old matrix.
  	        canvas.restore(); 
  	    }
	}
}
